﻿using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Eneta.Portal.Common;
using Eneta.Portal.Common.Dto;
using Eneta.Portal.Common.Repository;
using Microsoft.SharePoint;
using OfficeOpenXml;

namespace Eneta.Portal.Events.Controls
{
    public class EventControl : UserControl 
    {
        protected Label titleField;
        protected HtmlGenericControl teaserField;
        protected HtmlGenericControl descriptionField;

        protected HtmlGenericControl dateField;
        protected HtmlGenericControl timeField;
        protected HtmlAnchor levelLink;
        //protected HtmlGenericControl targetField;
        protected HtmlAnchor locationLink;
        protected HtmlGenericControl slidesVsDemoField;

        protected HtmlGenericControl registerEventDateField;
        protected HtmlGenericControl registerEventTitleField;
        protected HtmlGenericControl registrationWarningMessage;
        protected HtmlGenericControl attendingContainer;
        protected HtmlGenericControl registerToRealEventContainer;
        protected HtmlGenericControl registerToVirtualEventContainer;

        protected HtmlAnchor attendingUserProfileLink;
        protected HtmlImage attendingUserProfileImage;

        protected LinkButton registerToRealEventCommand;
        protected LinkButton registerToVirtualEventCommand;
        protected LinkButton unregisterCommand;

        protected HtmlGenericControl realAttendeeCountLabel;
        protected Repeater realAttendeesList;
        protected HtmlGenericControl virtualAttendeeCountLabel;
        protected Repeater virtualAttendeesList;

        protected HtmlGenericControl loginContainer;
        protected LinkButton loginCommand;
        protected HtmlGenericControl CommentsCount;
        protected Repeater CommentsRepeater;
        protected HtmlGenericControl AddCommentContainer;
        protected HtmlAnchor AddCommentProfileLink;
        protected HtmlImage AddCommentProfileImage;
        protected TextBox CommentField;
        protected Button SubmitComment;

        protected HtmlGenericControl CommandButtons;
        protected Button EditEvent;
        protected Button ExportToExcel;

        protected HtmlGenericControl realAttendeesContainer;
        protected HtmlGenericControl onlineAttendeesContainer;

        protected Repeater targetAudiences;

        private EventRepository _repository;
        private EventRepository Repository
        {
            get
            {
                if (_repository != null)
                    return _repository;

                _repository = new EventRepository(SPContext.Current.Web);
                return _repository;
            }
        }

        private EventDto _event;
        private EventDto Event
        {
            get
            {
                if (_event != null)
                    return _event;

                _event = Repository.GetEventById(SPContext.Current.ItemId);
                return _event;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            registerToRealEventCommand.Click += RegisterToRealEventCommandClick;
            registerToVirtualEventCommand.Click += RegisterToVirtualEventCommandClick;
            if (unregisterCommand == null)
                unregisterCommand = (LinkButton) attendingContainer.FindControl("unregisterCommand");
            unregisterCommand.Click += UnregisterCommandClick;
            loginCommand.Click += loginCommand_Click;
            SubmitComment.Click += SubmitComment_Click;
            EditEvent.Click += EditEvent_Click;
            ExportToExcel.Click += ExportToExcel_Click;
        }

        void loginCommand_Click(object sender, EventArgs e)
        {
            var url = "/_layouts/Eneta.Portal.Authentication/LiveAuthHandler.aspx?action=login&ReturnUrl=" + HttpUtility.UrlEncode(Page.Request.RawUrl);
            Response.Redirect(url);
        }

        void ExportToExcel_Click(object sender, EventArgs e)
        {
            var fileInfo = new FileInfo(Path.GetTempPath() + "\\" + DateTime.Now.Ticks + ".xlsx");
            var reg = Repository.GetEventAttendees(Event.Id);

            using (var xls = new ExcelPackage(fileInfo))
            {
                var sheet = xls.Workbook.Worksheets.Add(Event.Title);

                sheet.Cell(1, 1).Value = "Eesnimi";
                sheet.Cell(1, 2).Value = "Perekonnanimi";
                sheet.Cell(1, 3).Value = "Firma";
                sheet.Cell(1, 4).Value = "Kool";
                sheet.Cell(1, 5).Value = "E-post";
                sheet.Cell(1, 6).Value = "Telefon";
                sheet.Cell(1, 7).Value = "Registreerus";
                sheet.Cell(1, 8).Value = "Online";

                var i = 1;
                foreach(var att in reg)
                {
                    i++;

                    var profile = att.Attendee;
                    sheet.Cell(i, 1).Value = "" + profile.FirstName;
                    sheet.Cell(i, 2).Value = "" + profile.LastName;
                    sheet.Cell(i, 3).Value = "" + profile.Company;
                    sheet.Cell(i, 4).Value = "" + profile.School;
                    sheet.Cell(i, 5).Value = "" + profile.Email;
                    sheet.Cell(i, 6).Value = "" + profile.Phone;
                    sheet.Cell(i, 7).Value = "" + att.Created;
                    sheet.Cell(i, 8).Value = "" + att.OnlineAttendee;
                }

                xls.Save();  
            }

            Response.Clear();
            Response.ContentType = "application/vnd.openxmlformats";
            Response.AddHeader("Content-Disposition", "attachment; filename=" + fileInfo.Name);
            Response.WriteFile(fileInfo.FullName);
            Response.Flush();

            if (fileInfo.Exists)
                fileInfo.Delete();
        }

        void EditEvent_Click(object sender, EventArgs e)
        {
            Response.Redirect("/sundmused/lehed/add.aspx?EventID=" + Event.Id);
        }

        void SubmitComment_Click(object sender, EventArgs e)
        {
            var siteId = SPContext.Current.Site.ID;
            var userName = SPContext.Current.Web.CurrentUser.LoginName;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb("/sundmused/"))
                    {
                        var list = web.Lists["Comments"];
                        var item = list.Items.Add();
                        item["Body"] = CommentField.Text;

                        var authorFieldId = item.Fields.GetFieldByInternalName("Author").Id;
                        item[authorFieldId] = web.SiteUsers[userName];

                        var pageValue = new SPFieldLookupValue(Event.Id, Event.Title);
                        item["Event"] = pageValue;

                        item.Update();
                        list.Update();
                    }
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);
            Response.Redirect(Request.RawUrl, true);
        }

        void UnregisterCommandClick(object sender, EventArgs e)
        {
            if (Event == null)
                return;

            var user = SPContext.Current.Web.CurrentUser;
            Repository.RemoveRegistration(user, Event.Id);
            Response.Redirect(Request.RawUrl + "#jump-reg-1", false);
        }

        void RegisterToVirtualEventCommandClick(object sender, EventArgs e)
        {
            var user = SPContext.Current.Web.CurrentUser; 
            if (user == null)
            {
                Response.Redirect("/_layouts/Eneta.Portal.Authentication/LiveAuthHandler.aspx?action=login&ReturlUrl=" + HttpUtility.UrlEncode(Request.RawUrl));
            }
            else
            {
                Repository.RegiterUserToEvent(user, Event.Id, true);
                Response.Redirect(Request.RawUrl + "#jump-reg-1", false);
            }
        }

        void RegisterToRealEventCommandClick(object sender, EventArgs e)
        {
            var user = SPContext.Current.Web.CurrentUser;
            if (user == null)
            {
                Response.Redirect("/_layouts/Eneta.Portal.Authentication/LiveAuthHandler.aspx?action=login&ReturlUrl=" + HttpUtility.UrlEncode(Request.RawUrl));
            }
            else
            {
                Repository.RegiterUserToEvent(user, Event.Id, false);
                Response.Redirect(Request.RawUrl + "#jump-reg-1", false);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            registrationWarningMessage.InnerText = string.Empty;
            registrationWarningMessage.Visible = false;
            loginContainer.Visible = false;
            attendingContainer.Visible = false;
            registerToRealEventContainer.Visible = false;
            registerToVirtualEventContainer.Visible = false;
            
            if (IsPostBack)
                return;

            if (CommandButtons != null)
                CommandButtons.Visible = CurrentUserIsAdmin;

            if (Event == null)
            {
                Response.Redirect("/sundmused/");
                return;
            }

            BindEventDetails();
            SetEventStateForUser();

            realAttendeesContainer.Visible = Event.HasRealEvent;
            onlineAttendeesContainer.Visible = Event.HasVirtualEvent;

            var attendees = Repository.GetEventAttendees(Event.Id);

            var realAttendees = from a in attendees
                       where a.OnlineAttendee == false
                       select a;

            realAttendeeCountLabel.InnerText = realAttendees.Count().ToString();
            realAttendeesList.DataSource = realAttendees;
            realAttendeesList.DataBind();

            var virtualAttendees = from a in attendees
                       where a.OnlineAttendee
                       select a;

            virtualAttendeeCountLabel.InnerText = virtualAttendees.Count().ToString();
            virtualAttendeesList.DataSource = virtualAttendees;
            virtualAttendeesList.DataBind();

            BindComments();
        }

        private void BindComments()
        {
            AddCommentContainer.Visible = (SPContext.Current.Web.CurrentUser != null);

            var comments = Repository.GetEventComments(Event.Id);
            CommentsCount.InnerText = comments.Count.ToString();
            CommentsRepeater.DataSource = comments;
            CommentsRepeater.DataBind();
        }

        public static string GetUserProfileLink(HttpContext context)
        {
            var user = SPContext.Current.Web.CurrentUser;
            if (user == null)
                return string.Empty;

            var rep = new UserProfileRepository(SPContext.Current.Web);
            var profile = rep.GetUserProfileByUserName(user.LoginName);
            if (profile == null)
                return string.Empty;

            var profileLink = "<a href=\"profile.aspx?id=" + profile.Id + "\" title=\"" + profile.UserName + "\">";
            profileLink += profile.UserName + "</a>";

            return profileLink;
        }

        private void SetEventStateForUser()
        {
            var user = SPContext.Current.Web.CurrentUser;
            
            if(user==null)
            {
                if (Event.RegistrationEndDate < DateTime.Now.Date)
                {
                    registrationWarningMessage.InnerText = "Registreerumine on lõppenud";
                    registrationWarningMessage.Visible = true;
                    return;
                }

                loginContainer.Visible = true;
                return;
            }

            var registered = Repository.IsRegistered(user, Event.Id);

            if(!registered)
                if (Event.RegistrationEndDate < DateTime.Now.Date)
                {
                    registrationWarningMessage.InnerText = "Registreerumine on lõppenud";
                    registrationWarningMessage.Visible = true;
                    return;
                }

            if(registered)
            {
                var profileRepository = new UserProfileRepository(SPContext.Current.Web);
                var profile = profileRepository.GetUserProfileByUserName(user.LoginName);

                if (profile == null)
                {
                    return;
                }
                if (attendingUserProfileLink == null)
                    attendingUserProfileLink = (HtmlAnchor)attendingContainer.FindControl("attendingUserProfileLink");
                attendingUserProfileLink.HRef = "/profile.aspx?ID=" + profile.Id;

                if (attendingUserProfileImage == null)
                    attendingUserProfileImage = (HtmlImage)attendingContainer.FindControl("attendingUserProfileImage");
                attendingUserProfileImage.Src = profile.UserImage32x32Url;

                var attendingUserNameField = (HtmlGenericControl)attendingContainer.FindControl("attendingUserNameField");
                attendingUserNameField.InnerText = profile.UserName;

                attendingContainer.Visible = true;

                if (Event.EndTime <= DateTime.Now)
                    unregisterCommand.Visible = false;

                return;
            }

            var registrations = Repository.GetRegistrationsCount(Event.Id);
            if(registrations >= Event.MaxAttendees)
            {
                registrationWarningMessage.InnerText = "Kohtade arv on täis";
                registrationWarningMessage.Visible = true;
            }
            else 
                registerToRealEventContainer.Visible = Event.HasRealEvent;

            registerToVirtualEventContainer.Visible = Event.HasVirtualEvent;
        }

        private void BindEventDetails()
        {
            titleField.Text = Event.Title;
            teaserField.InnerText = Event.ShortDescription;
            descriptionField.InnerHtml = Event.Description;

            if (Event.StartTime.Date == Event.EndTime.Date)
            {
                dateField.InnerText = Event.StartTime.ToString("dd.MM.yyyy");
                timeField.InnerText = string.Empty;
            }
            else
            {
                dateField.InnerText = Event.StartTime.ToString("dd.MM.yyyy");
                dateField.InnerText += " - " + Event.EndTime.ToString("dd.MM.yyyy");

                timeField.InnerText = "iga päev ";
            }

            timeField.InnerText += Event.StartTime.ToString("HH:mm");
            timeField.InnerText += " - ";
            timeField.InnerText += Event.EndTime.ToString("HH:mm");

            locationLink.InnerText = Event.Location;
            locationLink.HRef = Event.LocationUrl;
            //targetField.InnerText = Event.Audience;
            try
            {
                targetAudiences.DataSource = Event.Audiences;
                targetAudiences.DataBind();
            }
            catch(Exception ex)
            {
                if (targetAudiences == null)
                    Logger.LogWarning("targetAudiences is null","");
                if (Event == null)
                    Logger.LogWarning("Event == null","");
            }
            levelLink.InnerText = Event.TechnicalLevel;
            slidesVsDemoField.InnerText = Event.PercentOfSlides + " / " + Event.PercentOfDemos;

            registerEventTitleField.InnerText = Event.Title;
            registerEventDateField.InnerText = Event.StartTime.ToString("dd.MM.yyyy");
        }

        public static string GetPromoBox(HttpContext context)
        {
            var user = SPContext.Current.Web.CurrentUser;
            if (user == null)
            {
                var output =
                    @"<p><a href=""/_layouts/Eneta.Portal.Authentication/LiveAuthHandler.aspx?action=login"">Logi sisse</a> ja lisa oma arvamus!</p>
					<p>Eneta portaali saad kasutada oma Live ID kontoga - see on sama, millega 
					suhtled Messengeris. Logi sisse, sest Enetas saad lisaks kommenteerimisele 
					<a href=""/kommuun/eneta/Lehed/liikmed.aspx"">teha palju muud põnevat</a>.</p>";
                return output;
            }

            var rep = new UserProfileRepository(SPContext.Current.Web);
            var profile = rep.GetUserProfileByUserName(user.LoginName);
            if (profile == null)
                return string.Empty;

            var output2 = "<p>{0} <a href='/uudised/teated/AddAnnouncement.aspx'>kirjuta uudis</a> või <a href='/addblog.aspx'>lisa oma blogi</a>.</p>";
            output2 = string.Format(output2, profile.UserName);
            return output2;
        }

        private bool CurrentUserIsAdmin
        {
            get
            {
                var user = SPContext.Current.Web.CurrentUser;
                if (user == null)
                    return false;

                return user.IsSiteAdmin;
            }
        }
    }
}
